
/*
 * Copyright 2002-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 *版权所有2002-2021原作者。
 *
 *根据Apache许可证2.0版（“许可证”）许可；
 *除非符合许可证的规定，否则您不得使用此文件。
 *您可以在以下网址获取许可证副本
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *除非适用法律要求或书面同意，否则软件
 *根据许可证分发是在“按原样”的基础上分发的，
 *无任何明示或暗示的保证或条件。
 *有关管理权限的特定语言，请参阅许可证
 *许可证下的限制。
 */

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Enables support for handling components marked with AspectJ's {@code @Aspect} annotation,
 * similar to functionality found in Spring's {@code <aop:aspectj-autoproxy>} XML element.
 * To be used on @{@link Configuration} classes as follows:
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;EnableAspectJAutoProxy
 * public class AppConfig {
 *
 *     &#064;Bean
 *     public FooService fooService() {
 *         return new FooService();
 *     }
 *
 *     &#064;Bean
 *     public MyAspect myAspect() {
 *         return new MyAspect();
 *     }
 * }</pre>
 *
 * Where {@code FooService} is a typical POJO component and {@code MyAspect} is an
 * {@code @Aspect}-style aspect:
 *
 * <pre class="code">
 * public class FooService {
 *
 *     // various methods
 * }</pre>
 *
 * <pre class="code">
 * &#064;Aspect
 * public class MyAspect {
 *
 *     &#064;Before("execution(* FooService+.*(..))")
 *     public void advice() {
 *         // advise FooService methods as appropriate
 *     }
 * }</pre>
 *
 * In the scenario above, {@code @EnableAspectJAutoProxy} ensures that {@code MyAspect}
 * will be properly processed and that {@code FooService} will be proxied mixing in the
 * advice that it contributes.
 *
 * <p>Users can control the type of proxy that gets created for {@code FooService} using
 * the {@link #proxyTargetClass()} attribute. The following enables CGLIB-style 'subclass'
 * proxies as opposed to the default interface-based JDK proxy approach.
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;EnableAspectJAutoProxy(proxyTargetClass=true)
 * public class AppConfig {
 *     // ...
 * }</pre>
 *
 * <p>Note that {@code @Aspect} beans may be component-scanned like any other.
 * Simply mark the aspect with both {@code @Aspect} and {@code @Component}:
 *
 * <pre class="code">
 * package com.foo;
 *
 * &#064;Component
 * public class FooService { ... }
 *
 * &#064;Aspect
 * &#064;Component
 * public class MyAspect { ... }</pre>
 *
 * Then use the @{@link ComponentScan} annotation to pick both up:
 *
 * <pre class="code">
 * &#064;Configuration
 * &#064;ComponentScan("com.foo")
 * &#064;EnableAspectJAutoProxy
 * public class AppConfig {
 *
 *     // no explicit &#064;Bean definitions required
 * }</pre>
 *
 * <b>Note: {@code @EnableAspectJAutoProxy} applies to its local application context only,
 * allowing for selective proxying of beans at different levels.</b> Please redeclare
 * {@code @EnableAspectJAutoProxy} in each individual context, e.g. the common root web
 * application context and any separate {@code DispatcherServlet} application contexts,
 * if you need to apply its behavior at multiple levels.
 *
 * <p>This feature requires the presence of {@code aspectjweaver} on the classpath.
 * While that dependency is optional for {@code spring-aop} in general, it is required
 * for {@code @EnableAspectJAutoProxy} and its underlying facilities.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @since 3.1
 * @see org.aspectj.lang.annotation.Aspect
 */
/**
 *支持处理用AspectJ的{@code@Aspect}注释标记的组件，
 *类似于Spring的{@code<aop:aspectj-autoproxy>}XML元素中的功能。
 *用于@｛@link配置｝类，如下所示：
 *
 *<pre-class=“code”>
 * &#064;配置
 * &#064;启用AspectJAutoProxy
 *公共类AppConfig{
 *
 *     &#064;豆
 *公共FooService FooService（）{
 *返回new FooService（）；
 *     }
 *
 *     &#064;豆
 *公共MyAspect MyAspect（）{
 *返回new MyAspect（）；
 *     }
 *}</pre>
 *
 *其中{@code FooService}是一个典型的POJO组件，{@code MyAspect}是
 *｛@code@Aspect｝-样式方面：
 *
 *<pre-class=“code”>
 *公共类FooService{
 *
 *//各种方法
 *}</pre>
 *
 *<pre-class=“code”>
 * &#064;方面
 *公共类MyAspect{
 *
 *     &#064;之前（“执行（*FooService+.*（..））”）
 *公共无效建议（）{
 *//酌情建议FooService方法
 *     }
 *}</pre>
 *
 *在上面的场景中，｛@code@EnableAspectJAutoProxy｝确保｛@code MyAspect｝
 *将被正确处理，并且｛@code FooService｝将被代理在
 *它提供的建议。
 *
 *＜p＞用户可以使用控制为｛@code FooService｝创建的代理类型
 *｛@link#proxyTargetClass（）｝属性。以下内容启用了CGLIB样式的“子类”
 *代理，而不是默认的基于接口的JDK代理方法。
 *
 *<pre-class=“code”>
 * &#064;配置
 * &#064;EnableAspectJAutoProxy（proxyTargetClass=true）
 *公共类AppConfig{
 *     // ...
 *}</pre>
 *
 *<p>请注意，{@code@Aspect}bean可以像其他任何bean一样进行组件扫描。
 *只需使用{@code@aspect}和{@code@Component}标记方面：
 *
 *<pre-class=“code”>
 *包com.foo；
 *
 * &#064;组成部分
 *公共类FooService｛…｝
 *
 * &#064;方面
 * &#064;组成部分
 *公共类MyAspect｛…｝</pre>
 *
 *然后使用@｛@link ComponentScan｝注释来拾取这两个：
 *
 *<pre-class=“code”>
 * &#064;配置
 * &#064;组件扫描（“com.foo”）
 * &#064;启用AspectJAutoProxy
 *公共类AppConfig{
 *
 *//没有明确的&#064；需要Bean定义
 *}</pre>
 *
 *＜b＞注意：｛@code@EnableAspectJAutoProxy｝仅适用于其本地应用程序上下文，
 *从而允许在不同水平上选择性地代理豆</b> 请重新申报
 *｛@code@EnableAspectJAutoProxy｝在每个单独的上下文中，例如公共根web
 *应用程序上下文和任何单独的{@code DispatcherServlet}应用程序上下文，
 *如果您需要在多个级别应用它的行为。
 *
 *<p>此功能要求类路径上存在{@code aspectjweaver}。
 *虽然该依赖关系通常对于{@code-spring-aop}是可选的，但它是必需的
 *用于{@code@EnableAspectJAutoProxy}及其底层设施。
 *
 *@作者Chris Beams
 *@作者Juergen Hoeller
 *@自3.1起
 *@参见org.aspectj.lang.annotation.Aspect
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies. The default is {@code false}.
	 */
	/**
	 *指示是否创建基于子类的（CGLIB）代理
	 *到标准的基于Java接口的代理。默认值为｛@code false｝。
	 */
	boolean proxyTargetClass() default false;

	/**
	 * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
	 * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
	 * Off by default, i.e. no guarantees that {@code AopContext} access will work.
	 * @since 4.3.1
	 */
	/**
	 *指示AOP框架应将代理公开为{@code ThreadLocal}
	 *用于通过{@linkorg.springframework.aop.framework.AopContext}类进行检索。
	 *默认情况下为关闭，即不能保证｛@code AoPontext｝访问将起作用。
	 *@自4.3.1起
	 */
	boolean exposeProxy() default false;

}
